package com.ewancle.studiousfamilybackend.handler;

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;

import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import com.ewancle.studiousfamilybackend.utils.ClientCache;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Component
public class SocketIOHandler  {

    private final SocketIOServer socketIoServer;

    private final ClientCache clientCache;

    public SocketIOHandler(SocketIOServer socketIoServer, ClientCache clientCache) {
        this.socketIoServer = socketIoServer;
        this.clientCache = clientCache;
    }

    // 连接成功就会调用此方法
    @OnConnect
    public void onConnect(SocketIOClient client){
        client.sendEvent("message", "conn ok");
        log.info(String.format("连接成功 %s",client.getSessionId()));
    }


    //测试使用
    @OnEvent("socketIOHandler")
    public void testHandler(SocketIOClient client, String data, AckRequest ackRequest) throws JsonProcessingException {

        log.info("SocketIOHandler:{}",data);

        if(ackRequest.isAckRequested()){
            //返回给客户端，说我接收到了
            ackRequest.sendAckData("SocketIOHandler",data);
        }

    }

    //加入房间
    @OnEvent("joinRoom")
    public void joinRooms(SocketIOClient client, String data, AckRequest ackRequest) throws JsonProcessingException {

        client.joinRoom(data);

        if(ackRequest.isAckRequested()){
            //返回给客户端，说我接收到了
            ackRequest.sendAckData("加入房间","成功");
        }

    }

    //离开房间
    @OnEvent("leaveRoom")
    public void leaveRoom(SocketIOClient client, String data, AckRequest ackRequest) throws JsonProcessingException {

        client.leaveRoom(data);

        if(ackRequest.isAckRequested()){
            //返回给客户端，说我接收到了
            ackRequest.sendAckData("离开房间","成功");
        }

    }


    //获取该用户所有房间
    @OnEvent("getUserRooms")
    public void getUserRooms(SocketIOClient client, String data, AckRequest ackRequest) throws JsonProcessingException {

        String userId = client.getHandshakeData().getSingleUrlParam("userId");

        Set<String> allRooms = client.getAllRooms();

        for (String room:allRooms){
            System.out.println("房间名称："+room);
        }

        log.info("服务器收到消息,客户端用户id：{} | 客户发送的消息：{} | 是否需要返回给客户端内容:{} ",userId,data,ackRequest.isAckRequested());


        if(ackRequest.isAckRequested()){
            //返回给客户端，说我接收到了
            ackRequest.sendAckData("你好","哈哈哈");
        }


    }

    @OnEvent("sendRoomMessage")
    public void sendRoomMessage(SocketIOClient client, String data, AckRequest ackRequest) throws JsonProcessingException {


        String userId = client.getHandshakeData().getSingleUrlParam("userId");


        Set<String> allRooms = client.getAllRooms();

        for (String room:allRooms){
            log.info("房间：{}",room);
            //发送给指定空间名称以及房间的人，并且排除不发给自己
            socketIoServer.getNamespace("/socketIO").getRoomOperations(room).sendEvent("message",client, data);

            //发送给指定空间名称以及房间的人，包括自己
            //socketIoServer.getNamespace("/socketIO").getRoomOperations(room).sendEvent("message", data);;
        }



        if(ackRequest.isAckRequested()){
            //返回给客户端，说我接收到了
            ackRequest.sendAckData("发送消息到指定的房间","成功");
        }

    }

    //广播消息给指定的Namespace下所有客户端
    @OnEvent("sendNamespaceMessage")
    public void sendNamespaceMessage(SocketIOClient client, String data, AckRequest ackRequest) throws JsonProcessingException {


        socketIoServer.getNamespace("/socketIO").getBroadcastOperations().sendEvent("message",client, data);;


        if(ackRequest.isAckRequested()){
            //返回给客户端，说我接收到了
            ackRequest.sendAckData("发送消息到指定的房间","成功");
        }

    }

    /**
     * 广播消息
     */
    public void sendBroadcast() {
        Collection<HashMap<UUID, SocketIOClient>> data = clientCache.getAllClient().values();
        List<SocketIOClient> allListData = new ArrayList<>();
        if(!CollectionUtils.isEmpty(data)){
            allListData = data.parallelStream().flatMap(item -> item.values().stream()).toList();
        }
        for (SocketIOClient client : allListData) {
            if (client.isChannelOpen()) {
                client.sendEvent("Broadcast", "当前时间", System.currentTimeMillis());
            }
        }

    }


    //点对点
    public void sendMessageOne(String userId) throws JsonProcessingException {


        HashMap<UUID, SocketIOClient> userClient = clientCache.getUserClient(userId);

        for (UUID sessionId : userClient.keySet()) {
            socketIoServer.getNamespace("/socketIO").getClient(sessionId).sendEvent("message", "这是点对点发送");
        }

    }




}